using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using DocumentCreationSystem.Models;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 增强文件访问服务
    /// 提供智能文件访问、路径管理和内容分析功能
    /// </summary>
    public class EnhancedFileAccessService
    {
        private readonly ILogger<EnhancedFileAccessService> _logger;
        private readonly Dictionary<string, FileAccessStrategy> _fileStrategies = new();
        
        // 文件大小阈值配置
        private const long SMALL_FILE_THRESHOLD = 1024 * 10;      // 10KB - 完整读取
        private const long MEDIUM_FILE_THRESHOLD = 1024 * 100;    // 100KB - 部分读取
        private const long LARGE_FILE_THRESHOLD = 1024 * 1024;    // 1MB - 摘要读取
        
        // 支持的文本文件扩展名
        private readonly HashSet<string> _textExtensions = new(StringComparer.OrdinalIgnoreCase)
        {
            ".txt", ".md", ".json", ".xml", ".csv", ".log", ".config", ".ini", 
            ".yaml", ".yml", ".html", ".htm", ".css", ".js", ".ts", ".cs", 
            ".py", ".java", ".cpp", ".h", ".sql", ".bat", ".ps1", ".sh"
        };

        public EnhancedFileAccessService(ILogger<EnhancedFileAccessService> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 智能获取路径信息
        /// </summary>
        /// <param name="targetPath">目标路径</param>
        /// <param name="includeHidden">是否包含隐藏文件</param>
        /// <param name="maxDepth">最大递归深度</param>
        /// <returns>路径信息结果</returns>
        public async Task<PathInfoResult> GetPathInfoAsync(string targetPath, bool includeHidden = false, int maxDepth = 3)
        {
            var result = new PathInfoResult
            {
                TargetPath = targetPath,
                Timestamp = DateTime.Now
            };

            try
            {
                if (!Path.Exists(targetPath))
                {
                    result.ErrorMessage = $"路径不存在: {targetPath}";
                    return result;
                }

                var fullPath = Path.GetFullPath(targetPath);
                result.FullPath = fullPath;
                result.IsDirectory = Directory.Exists(fullPath);
                result.IsFile = File.Exists(fullPath);

                if (result.IsDirectory)
                {
                    await AnalyzeDirectoryAsync(result, fullPath, includeHidden, maxDepth);
                }
                else if (result.IsFile)
                {
                    await AnalyzeFileAsync(result, fullPath);
                }

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取路径信息失败: {targetPath}");
                result.ErrorMessage = ex.Message;
                return result;
            }
        }

        /// <summary>
        /// 智能文件内容访问
        /// </summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="accessMode">访问模式</param>
        /// <returns>文件内容结果</returns>
        public async Task<FileContentResult> GetFileContentAsync(string filePath, FileAccessMode accessMode = FileAccessMode.Auto)
        {
            var result = new FileContentResult
            {
                FilePath = filePath,
                Timestamp = DateTime.Now
            };

            try
            {
                if (!File.Exists(filePath))
                {
                    result.ErrorMessage = $"文件不存在: {filePath}";
                    return result;
                }

                var fileInfo = new FileInfo(filePath);
                result.FileSize = fileInfo.Length;
                result.LastModified = fileInfo.LastWriteTime;
                result.Extension = fileInfo.Extension;
                result.IsTextFile = _textExtensions.Contains(fileInfo.Extension);

                // 确定访问策略
                var strategy = DetermineAccessStrategy(fileInfo, accessMode);
                result.AccessStrategy = strategy;

                // 根据策略读取内容
                await ReadFileContentByStrategy(result, filePath, strategy);

                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"读取文件内容失败: {filePath}");
                result.ErrorMessage = ex.Message;
                return result;
            }
        }

        /// <summary>
        /// 批量文件信息获取
        /// </summary>
        /// <param name="filePaths">文件路径列表</param>
        /// <param name="includeContent">是否包含内容</param>
        /// <returns>批量文件信息结果</returns>
        public async Task<BatchFileInfoResult> GetBatchFileInfoAsync(IEnumerable<string> filePaths, bool includeContent = false)
        {
            var result = new BatchFileInfoResult
            {
                Timestamp = DateTime.Now
            };

            var tasks = filePaths.Select(async path =>
            {
                try
                {
                    var fileInfo = new FileInfo(path);
                    var info = new FileInfoItem
                    {
                        FilePath = path,
                        FileName = fileInfo.Name,
                        FileSize = fileInfo.Length,
                        LastModified = fileInfo.LastWriteTime,
                        Extension = fileInfo.Extension,
                        IsTextFile = _textExtensions.Contains(fileInfo.Extension),
                        Exists = fileInfo.Exists
                    };

                    if (includeContent && info.IsTextFile && info.FileSize < MEDIUM_FILE_THRESHOLD)
                    {
                        var contentResult = await GetFileContentAsync(path, FileAccessMode.Smart);
                        info.ContentPreview = contentResult.Content?.Substring(0, Math.Min(500, contentResult.Content?.Length ?? 0));
                        info.AccessStrategy = contentResult.AccessStrategy;
                    }

                    return info;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"获取文件信息失败: {path}");
                    return new FileInfoItem
                    {
                        FilePath = path,
                        ErrorMessage = ex.Message,
                        Exists = false
                    };
                }
            });

            result.Files = (await Task.WhenAll(tasks)).ToList();
            result.TotalFiles = result.Files.Count;
            result.ValidFiles = result.Files.Count(f => f.Exists);
            result.TextFiles = result.Files.Count(f => f.IsTextFile);
            result.TotalSize = result.Files.Where(f => f.Exists).Sum(f => f.FileSize);

            return result;
        }

        /// <summary>
        /// 智能路径搜索
        /// </summary>
        /// <param name="basePath">基础路径</param>
        /// <param name="searchPattern">搜索模式</param>
        /// <param name="searchOptions">搜索选项</param>
        /// <returns>搜索结果</returns>
        public async Task<PathSearchResult> SearchPathsAsync(string basePath, string searchPattern, PathSearchOptions searchOptions = null)
        {
            searchOptions ??= new PathSearchOptions();
            
            var result = new PathSearchResult
            {
                BasePath = basePath,
                SearchPattern = searchPattern,
                Timestamp = DateTime.Now
            };

            try
            {
                if (!Directory.Exists(basePath))
                {
                    result.ErrorMessage = $"基础路径不存在: {basePath}";
                    return result;
                }

                var searchOption = searchOptions.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
                
                // 搜索文件
                if (searchOptions.IncludeFiles)
                {
                    var files = Directory.GetFiles(basePath, searchPattern, searchOption);
                    result.MatchedFiles = files.Take(searchOptions.MaxResults).ToList();
                }

                // 搜索目录
                if (searchOptions.IncludeDirectories)
                {
                    var directories = Directory.GetDirectories(basePath, searchPattern, searchOption);
                    result.MatchedDirectories = directories.Take(searchOptions.MaxResults).ToList();
                }

                // 如果需要详细信息，获取文件信息
                if (searchOptions.IncludeDetailedInfo)
                {
                    var allPaths = result.MatchedFiles.Concat(result.MatchedDirectories);
                    var detailedInfo = await GetBatchFileInfoAsync(allPaths, searchOptions.IncludeContentPreview);
                    result.DetailedInfo = detailedInfo;
                }

                result.TotalMatches = result.MatchedFiles.Count + result.MatchedDirectories.Count;
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"路径搜索失败: {basePath}, 模式: {searchPattern}");
                result.ErrorMessage = ex.Message;
                return result;
            }
        }

        /// <summary>
        /// 分析目录
        /// </summary>
        private async Task AnalyzeDirectoryAsync(PathInfoResult result, string directoryPath, bool includeHidden, int maxDepth)
        {
            var dirInfo = new DirectoryInfo(directoryPath);
            result.Name = dirInfo.Name;
            result.LastModified = dirInfo.LastWriteTime;

            // 获取直接子项
            var files = dirInfo.GetFiles().Where(f => includeHidden || !f.Attributes.HasFlag(FileAttributes.Hidden));
            var directories = dirInfo.GetDirectories().Where(d => includeHidden || !d.Attributes.HasFlag(FileAttributes.Hidden));

            result.FileCount = files.Count();
            result.DirectoryCount = directories.Count();
            result.TotalSize = files.Sum(f => f.Length);

            // 构建目录树
            if (maxDepth > 0)
            {
                result.Children = new List<PathInfoResult>();
                
                // 添加文件
                foreach (var file in files.Take(50)) // 限制显示数量
                {
                    var fileResult = new PathInfoResult
                    {
                        TargetPath = file.FullName,
                        FullPath = file.FullName,
                        Name = file.Name,
                        IsFile = true,
                        FileSize = file.Length,
                        LastModified = file.LastWriteTime,
                        Extension = file.Extension
                    };
                    result.Children.Add(fileResult);
                }

                // 递归添加子目录
                foreach (var subDir in directories.Take(20)) // 限制递归数量
                {
                    var subResult = await GetPathInfoAsync(subDir.FullName, includeHidden, maxDepth - 1);
                    result.Children.Add(subResult);
                }
            }

            // 分析文件类型分布
            result.FileTypeDistribution = files
                .GroupBy(f => f.Extension.ToLower())
                .ToDictionary(g => g.Key, g => g.Count());
        }

        /// <summary>
        /// 分析文件
        /// </summary>
        private async Task AnalyzeFileAsync(PathInfoResult result, string filePath)
        {
            var fileInfo = new FileInfo(filePath);
            result.Name = fileInfo.Name;
            result.FileSize = fileInfo.Length;
            result.LastModified = fileInfo.LastWriteTime;
            result.Extension = fileInfo.Extension;
            result.IsTextFile = _textExtensions.Contains(fileInfo.Extension);

            // 如果是文本文件且不太大，获取内容摘要
            if (result.IsTextFile && result.FileSize < MEDIUM_FILE_THRESHOLD)
            {
                try
                {
                    var content = await File.ReadAllTextAsync(filePath);
                    result.ContentPreview = content.Length > 500 ? content.Substring(0, 500) + "..." : content;
                    result.LineCount = content.Split('\n').Length;
                    result.CharacterCount = content.Length;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, $"读取文件内容失败: {filePath}");
                }
            }
        }

        /// <summary>
        /// 确定文件访问策略
        /// </summary>
        private FileAccessStrategy DetermineAccessStrategy(FileInfo fileInfo, FileAccessMode accessMode)
        {
            if (accessMode == FileAccessMode.Full)
                return FileAccessStrategy.FullRead;
            if (accessMode == FileAccessMode.Summary)
                return FileAccessStrategy.SummaryOnly;
            if (accessMode == FileAccessMode.Preview)
                return FileAccessStrategy.PreviewOnly;

            // 自动模式 - 根据文件大小和类型智能判断
            if (!_textExtensions.Contains(fileInfo.Extension))
                return FileAccessStrategy.MetadataOnly;

            if (fileInfo.Length <= SMALL_FILE_THRESHOLD)
                return FileAccessStrategy.FullRead;
            else if (fileInfo.Length <= MEDIUM_FILE_THRESHOLD)
                return FileAccessStrategy.PartialRead;
            else if (fileInfo.Length <= LARGE_FILE_THRESHOLD)
                return FileAccessStrategy.PreviewOnly;
            else
                return FileAccessStrategy.SummaryOnly;
        }

        /// <summary>
        /// 根据策略读取文件内容
        /// </summary>
        private async Task ReadFileContentByStrategy(FileContentResult result, string filePath, FileAccessStrategy strategy)
        {
            switch (strategy)
            {
                case FileAccessStrategy.FullRead:
                    result.Content = await File.ReadAllTextAsync(filePath);
                    result.IsComplete = true;
                    break;

                case FileAccessStrategy.PartialRead:
                    await ReadPartialContent(result, filePath);
                    break;

                case FileAccessStrategy.PreviewOnly:
                    await ReadPreviewContent(result, filePath);
                    break;

                case FileAccessStrategy.SummaryOnly:
                    await GenerateSummary(result, filePath);
                    break;

                case FileAccessStrategy.MetadataOnly:
                    // 只有元数据，不读取内容
                    result.Content = "[二进制文件或不支持的格式]";
                    result.IsComplete = false;
                    break;
            }
        }

        /// <summary>
        /// 读取部分内容
        /// </summary>
        private async Task ReadPartialContent(FileContentResult result, string filePath)
        {
            var lines = await File.ReadAllLinesAsync(filePath);
            var totalLines = lines.Length;
            
            if (totalLines <= 100)
            {
                result.Content = string.Join("\n", lines);
                result.IsComplete = true;
            }
            else
            {
                // 读取开头50行和结尾20行
                var preview = lines.Take(50).Concat(new[] { "\n... [省略中间部分] ...\n" }).Concat(lines.TakeLast(20));
                result.Content = string.Join("\n", preview);
                result.IsComplete = false;
                result.TotalLines = totalLines;
                result.PreviewLines = 70;
            }
        }

        /// <summary>
        /// 读取预览内容
        /// </summary>
        private async Task ReadPreviewContent(FileContentResult result, string filePath)
        {
            using var reader = new StreamReader(filePath);
            var preview = new StringBuilder();
            var lineCount = 0;
            
            while (lineCount < 20 && !reader.EndOfStream)
            {
                var line = await reader.ReadLineAsync();
                preview.AppendLine(line);
                lineCount++;
            }
            
            result.Content = preview.ToString();
            result.IsComplete = false;
            result.PreviewLines = lineCount;
        }

        /// <summary>
        /// 生成文件摘要
        /// </summary>
        private async Task GenerateSummary(FileContentResult result, string filePath)
        {
            var fileInfo = new FileInfo(filePath);
            var summary = new StringBuilder();
            
            summary.AppendLine($"文件摘要: {fileInfo.Name}");
            summary.AppendLine($"大小: {FormatFileSize(fileInfo.Length)}");
            summary.AppendLine($"类型: {fileInfo.Extension}");
            summary.AppendLine($"修改时间: {fileInfo.LastWriteTime:yyyy-MM-dd HH:mm:ss}");
            
            if (result.IsTextFile)
            {
                try
                {
                    var lines = await File.ReadAllLinesAsync(filePath);
                    summary.AppendLine($"总行数: {lines.Length}");
                    
                    if (lines.Length > 0)
                    {
                        summary.AppendLine("前几行内容:");
                        for (int i = 0; i < Math.Min(5, lines.Length); i++)
                        {
                            var line = lines[i].Length > 100 ? lines[i].Substring(0, 100) + "..." : lines[i];
                            summary.AppendLine($"  {i + 1}: {line}");
                        }
                    }
                }
                catch (Exception ex)
                {
                    summary.AppendLine($"内容读取失败: {ex.Message}");
                }
            }
            
            result.Content = summary.ToString();
            result.IsComplete = false;
        }

        /// <summary>
        /// 格式化文件大小
        /// </summary>
        private string FormatFileSize(long bytes)
        {
            if (bytes < 1024) return $"{bytes} B";
            if (bytes < 1024 * 1024) return $"{bytes / 1024:F1} KB";
            if (bytes < 1024 * 1024 * 1024) return $"{bytes / (1024 * 1024):F1} MB";
            return $"{bytes / (1024 * 1024 * 1024):F1} GB";
        }
    }
}
